﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Routing;
using System.Xml;
using System.Xml.Serialization;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using Smarly.Bussines.Model;
using Smarly.Web.App_Start;
using Smarly.Web.Controllers;
using Smarly.Web.Controllers.Base;

namespace Smarly.Web.Storage
{
	public static class Rss
	{
		static readonly CloudBlobContainer container;
		static Rss()
		{
#if !DEBUG
			CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["AzureStorageConnectionString"].ConnectionString);
			CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
			container = blobClient.GetContainerReference("smarly");
			container.CreateIfNotExists();
			container.SetPermissions(new BlobContainerPermissions
			{
				PublicAccess = BlobContainerPublicAccessType.Blob
			});
#endif
		}

		public static void Init()
		{
			BaseController.SectionPublished += Update;
		}
		public static void Update(HttpRequestBase request)
		{
#if !DEBUG
			CloudBlockBlob blockBlob = container.GetBlockBlobReference("published.rss");

			var ns = new XmlSerializerNamespaces();
			ns.Add("atom", "http://www.w3.org/2005/Atom");

			NewsModel t = BookTree.GetNews();

			var obj = new RssSet();

			obj.channel.Title = "Новинки книг на smarly.net";
			obj.channel.Description =
				"Канал содержит новости публикаций новых переведенных на русский язык IT книг на smarly.net";
			obj.channel.Link = "http://smarly.net";
			obj.channel.RssLink = new Link() {
				Href = "http://storage.smarly.net/smarly/published.rss",
				Rel = "self",
				Type = "application/rss+xml",
			};

			var routes = new RouteCollection();
			RouteConfig.RegisterRoutes(routes);

			StringBuilder sb = new StringBuilder();

			DateTime lastUpdate = new DateTime();

			foreach (BookTree section in t.Sections)
			{
				var secDate = section.UpdateDate;
				var partsDate = section.Children.Select(x => x.UpdateDate).OrderByDescending(x => x).First();
				section.UpdateDate = secDate > partsDate ? secDate : partsDate;
			}

			foreach (BookTree section in t.Sections.OrderByDescending(x => x.UpdateDate))
			{
				Item item = new Item();
				item.Title = section.Text + " | " + section.Parent.Text;
				item.Link = "http://smarly.net" + section.Url;
				item.Guid = "http://smarly.net" + section.Url;

				var secDate = section.UpdateDate;
				//var partsDate = section.Children.Select(x => x.UpdateDate).OrderByDescending(x => x).First();



				sb.Clear();

				sb.AppendFormat(@"<div><div><img alt=""{3}"" src=""{5}""></div><div><p>Опубликована глава <a href=""{0}{2}"">{1}</a> книги <a href=""{0}{4}"">{3}</a><p>", "http://smarly.net", section.Text, section.Url, section.Parent.Text, section.Parent.Url, section.Book.CoverUrl);

				sb.Append("<p>Глава содержит следующие разделы</div>");
				sb.Append("<ol>");
				foreach (var child in section.Children)
				{
					sb.AppendFormat(@"<li><a href=""{0}{2}"">{1}</a></li>", "http://smarly.net", child.Text, child.Url);
					secDate = secDate > child.UpdateDate ? secDate : child.UpdateDate;
				}
				sb.Append("</ol>");

				sb.Append("</div></div>");

				item.PubDate = secDate.ToString("r", CultureInfo.CreateSpecificCulture("en-US"));
				lastUpdate = secDate > lastUpdate ? secDate : lastUpdate;


				item.Description = new NodeType()
					                   {
						                   Content = sb.ToString()
					                   };

				obj.channel.item.Add(item);
			}

			obj.channel.LastBuildDate = lastUpdate.ToString("r", CultureInfo.CreateSpecificCulture("en-US"));


			using (var stream = new MemoryStream())
			{
				var ser = new XmlSerializer(typeof(RssSet));
				ser.Serialize(stream, obj, ns);
				stream.Flush();
				stream.Position = 0;
				blockBlob.Properties.ContentType = "application/rss+xml; charset=utf-8";
				blockBlob.UploadFromStream(stream);

//				using (Stream file = File.OpenWrite(@"C:\inetpub\wwwroot\test.rss"))
//				{
//					CopyStream(stream, file);
//				}
			}
#endif


		}

//public static void CopyStream(Stream input, Stream output)
//{
//    byte[] buffer = new byte[8 * 1024];
//    int len;
//    while ( (len = input.Read(buffer, 0, buffer.Length)) > 0)
//    {
//        output.Write(buffer, 0, len);
//    }    
//}
	}


	[XmlRoot("rss")]
	public class RssSet
	{
		[XmlAttribute]
		public string version = "2.0";
		public Channel channel = new Channel();
	}

	[XmlRoot("channel")]
	public class Channel
	{
		[XmlElement("link", Namespace = "http://www.w3.org/2005/Atom", Order = 1)]
		public Link RssLink { get; set; }

		[XmlElement("link", Order = 2)]
		public string Link { get; set; }

		[XmlElement("title", Order = 3)]
		public string Title { get; set; }

		[XmlElement("description", Order = 4)]
		public string Description { get; set; }

		[XmlElement("lastBuildDate", Order = 5)]
		public string LastBuildDate { get; set; }

		[XmlElement("item", Order = 6)]
		public List<Item> item = new List<Item>();
	}

	public class Link
	{
		[XmlAttribute("href")]
		public string Href { get; set; }

		[XmlAttribute("rel")]
		public string Rel { get; set; }

		[XmlAttribute("type")]
		public string Type { get; set; }

	}

	public class Item
	{

		[XmlElement("title", Order = 1)]
		public string Title { get; set; }

		[XmlElement("link", Order = 2)]
		public string Link { get; set; }

		[XmlElement("guid", Order = 3)]
		public string Guid { get; set; }

		[XmlElement("pubDate", Order = 4)]
		public string PubDate { get; set; }

		[XmlElement("description", Order = 5)]
		public NodeType Description { get; set; }
	}

	public class NodeType
	{
		[XmlIgnore]
		public string Content { get; set; }

		[XmlText]
		public XmlNode[] CDataContent
		{
			get
			{
				var dummy = new XmlDocument();
				return new XmlNode[] { dummy.CreateCDataSection(Content) };
			}
			set
			{
				if (value == null)
				{
					Content = null;
					return;
				}

				if (value.Length != 1)
				{
					throw new InvalidOperationException(
							String.Format(
									"Invalid array length {0}", value.Length));
				}

				Content = value[0].Value;
			}
		}
	}
}